---
title: "函数和栈管理"
description: "从 JavaScript 视角学习 C 语言函数和栈管理。理解函数参数传递机制、栈帧、递归函数、函数指针和内存管理。"
---

# 函数和栈管理

## 1. 介绍

### 从 JavaScript 函数到 C 函数

在 JavaScript 中，函数是一等对象，具有闭包、自动内存管理和灵活的参数处理。在 C 中，函数更加原始，但提供了对内存、栈管理和性能优化的精确控制。

C 函数是模块化编程的基础构建块，提供：
- 代码重用和组织
- 对内存分配的精确控制
- 性能优化机会
- 系统级编程能力

> 💡 **核心概念**: C 函数在调用栈上运行，每次函数调用都会创建一个栈帧，包含局部变量、参数和返回地址。理解栈管理对内存安全和性能至关重要。

## 2. 函数基础

### 2.1 函数声明和定义

<UniversalEditor title="函数声明" compare={true}>
```javascript !! js
// JavaScript - 灵活的函数声明
function greet(name) {
    return `Hello, ${name}!`;
}

// 函数表达式
const greet2 = function(name) {
    return `Hello, ${name}!`;
};

// 箭头函数
const greet3 = (name) => `Hello, ${name}!`;

// 默认参数
function greetWithDefault(name = "World") {
    return `Hello, ${name}!`;
}

// 可变参数
function sum(...numbers) {
    return numbers.reduce((a, b) => a + b, 0);
}

// 函数调用
console.log(greet("Alice"));
console.log(greetWithDefault());
console.log(sum(1, 2, 3, 4, 5));
```

```c !! c
#include <stdio.h>

// 函数声明（原型）
int greet(const char* name);
int sum(int a, int b);
void printArray(int arr[], int size);

// 函数定义
int greet(const char* name) {
    printf("Hello, %s!\n", name);
    return 0;
}

// 带返回值的函数
int sum(int a, int b) {
    return a + b;
}

// 带数组参数的函数
void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

// 带多个参数的函数
int calculate(int a, int b, char operation) {
    switch (operation) {
        case '+': return a + b;
        case '-': return a - b;
        case '*': return a * b;
        case '/': return b != 0 ? a / b : 0;
        default: return 0;
    }
}

int main() {
    // 函数调用
    greet("Alice");
    
    int result = sum(10, 20);
    printf("Sum: %d\n", result);
    
    int arr[] = {1, 2, 3, 4, 5};
    printArray(arr, 5);
    
    printf("10 + 5 = %d\n", calculate(10, 5, '+'));
    printf("10 - 5 = %d\n", calculate(10, 5, '-'));
    
    return 0;
}
```
</UniversalEditor>

### 2.2 函数参数和栈帧

<UniversalEditor title="函数参数和栈" compare={true}>
```javascript !! js
// JavaScript - 基本类型按值传递，对象按引用传递
function modifyValue(x) {
    x = 100;  // 基本类型的局部副本
    console.log("函数内部:", x);
}

function modifyObject(obj) {
    obj.name = "Modified";  // 修改原始对象
    console.log("函数内部:", obj.name);
}

function modifyArray(arr) {
    arr.push(100);  // 修改原始数组
    console.log("函数内部:", arr);
}

// 测试不同类型
let num = 10;
let person = { name: "John" };
let numbers = [1, 2, 3];

console.log("修改前:", num, person.name, numbers);
modifyValue(num);
modifyObject(person);
modifyArray(numbers);
console.log("修改后:", num, person.name, numbers);
```

```c !! c
#include <stdio.h>

// 按值传递（C 中的默认方式）
void modifyValue(int x) {
    x = 100;  // 局部副本，不影响原始值
    printf("函数内部: x = %d\n", x);
}

// 按指针传递（模拟按引用传递）
void modifyValueByPointer(int* x) {
    *x = 100;  // 修改原始值
    printf("函数内部: *x = %d\n", *x);
}

// 按指针传递数组
void modifyArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        arr[i] *= 2;  // 修改原始数组
    }
    printf("函数内部: 数组已修改\n");
}

// 带局部变量的函数（栈帧）
void functionWithLocals(int param) {
    int local1 = 10;
    int local2 = 20;
    int local3 = local1 + local2 + param;
    
    printf("局部变量: %d, %d, %d\n", local1, local2, local3);
    printf("参数: %d\n", param);
    
    // 这些变量存储在函数的栈帧中
    // 函数返回时自动释放
}

int main() {
    int num = 10;
    int arr[] = {1, 2, 3, 4, 5};
    
    printf("修改前: num = %d\n", num);
    modifyValue(num);  // 按值传递
    printf("modifyValue 后: num = %d\n", num);
    
    modifyValueByPointer(&num);  // 按指针传递
    printf("modifyValueByPointer 后: num = %d\n", num);
    
    printf("数组修改前: ");
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    modifyArray(arr, 5);  // 按指针传递数组
    
    printf("数组修改后: ");
    for (int i = 0; i < 5; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    functionWithLocals(5);
    
    return 0;
}
```
</UniversalEditor>

### 2.3 栈帧结构

<UniversalEditor title="栈帧可视化" compare={true}>
```javascript !! js
// JavaScript - 自动栈管理
function outerFunction(x) {
    let outerVar = x * 2;
    
    function innerFunction(y) {
        let innerVar = y + outerVar;  // 闭包捕获 outerVar
        console.log("内部函数:", innerVar);
        return innerVar;
    }
    
    console.log("外部函数:", outerVar);
    return innerFunction(10);
}

// 函数调用创建执行上下文
let result = outerFunction(5);
console.log("结果:", result);

// 栈跟踪显示调用层次
function demonstrateStack() {
    console.trace("当前栈跟踪");
}

demonstrateStack();
```

```c !! c
#include <stdio.h>

// 演示栈帧的函数
void functionA(int param1, int param2) {
    int local1 = param1 + param2;
    int local2 = param1 * param2;
    
    printf("函数 A - 参数: %d, %d\n", param1, param2);
    printf("函数 A - 局部变量: %d, %d\n", local1, local2);
    
    // 栈帧结构:
    // +------------------+
    // | 返回地址         |  <- 函数返回后的地址
    // +------------------+
    // | param2           |  <- 函数参数
    // +------------------+
    // | param1           |
    // +------------------+
    // | local1           |  <- 局部变量
    // +------------------+
    // | local2           |
    // +------------------+
    // | 栈指针           |  <- 当前栈位置
    // +------------------+
}

void functionB(int x) {
    int local = x * 2;
    printf("函数 B - 参数: %d, 局部变量: %d\n", x, local);
    
    // 调用另一个函数（创建新的栈帧）
    functionA(x, local);
}

int main() {
    printf("主函数开始\n");
    
    // 每次函数调用都创建新的栈帧
    functionB(5);
    
    printf("主函数结束\n");
    return 0;
}
```
</UniversalEditor>

## 3. 递归和栈管理

### 3.1 递归函数

<UniversalEditor title="递归函数" compare={true}>
```javascript !! js
// JavaScript - 带自动栈管理的递归
function factorial(n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

function countdown(n) {
    if (n <= 0) {
        console.log("发射！");
        return;
    }
    console.log(n);
    countdown(n - 1);
}

// 递归数组处理
function sumArray(arr, index = 0) {
    if (index >= arr.length) return 0;
    return arr[index] + sumArray(arr, index + 1);
}

// 测试递归
console.log("5 的阶乘:", factorial(5));
console.log("斐波那契(7):", fibonacci(7));
countdown(3);
console.log("[1,2,3,4,5] 的和:", sumArray([1, 2, 3, 4, 5]));
```

```c !! c
#include <stdio.h>

// 递归阶乘函数
int factorial(int n) {
    if (n <= 1) {
        return 1;
    }
    return n * factorial(n - 1);
}

// 递归斐波那契（效率低但演示递归）
int fibonacci(int n) {
    if (n <= 1) {
        return n;
    }
    return fibonacci(n - 1) + fibonacci(n - 2);
}

// 递归倒计时
void countdown(int n) {
    if (n <= 0) {
        printf("发射！\n");
        return;
    }
    printf("%d\n", n);
    countdown(n - 1);
}

// 递归数组求和
int sumArray(int arr[], int size, int index) {
    if (index >= size) {
        return 0;
    }
    return arr[index] + sumArray(arr, size, index + 1);
}

// 递归二分查找
int binarySearch(int arr[], int left, int right, int target) {
    if (left > right) {
        return -1;  // 未找到
    }
    
    int mid = left + (right - left) / 2;
    
    if (arr[mid] == target) {
        return mid;
    } else if (arr[mid] > target) {
        return binarySearch(arr, left, mid - 1, target);
    } else {
        return binarySearch(arr, mid + 1, right, target);
    }
}

int main() {
    printf("5 的阶乘: %d\n", factorial(5));
    printf("斐波那契(7): %d\n", fibonacci(7));
    
    countdown(3);
    
    int arr[] = {1, 2, 3, 4, 5};
    printf("数组和: %d\n", sumArray(arr, 5, 0));
    
    int sorted[] = {1, 3, 5, 7, 9, 11, 13, 15};
    int target = 7;
    int result = binarySearch(sorted, 0, 7, target);
    printf("二分查找 %d: 索引 %d\n", target, result);
    
    return 0;
}
```
</UniversalEditor>

### 3.2 栈溢出和内存管理

<UniversalEditor title="栈溢出预防" compare={true}>
```javascript !! js
// JavaScript - 带限制的自动栈管理
function deepRecursion(n) {
    if (n <= 0) return 0;
    return 1 + deepRecursion(n - 1);
}

// JavaScript 有调用栈限制
try {
    console.log("深度递归结果:", deepRecursion(10000));
} catch (error) {
    console.log("栈溢出:", error.message);
}

// 尾递归优化（ES6）
function tailRecursiveFactorial(n, accumulator = 1) {
    if (n <= 1) return accumulator;
    return tailRecursiveFactorial(n - 1, n * accumulator);
}

console.log("尾递归阶乘:", tailRecursiveFactorial(5));
```

```c !! c
#include <stdio.h>
#include <stdlib.h>

// 可能导致栈溢出的深度递归
int deepRecursion(int n) {
    if (n <= 0) {
        return 0;
    }
    return 1 + deepRecursion(n - 1);
}

// 尾递归阶乘（更高效）
int tailRecursiveFactorial(int n, int accumulator) {
    if (n <= 1) {
        return accumulator;
    }
    return tailRecursiveFactorial(n - 1, n * accumulator);
}

// 迭代版本（防止栈溢出）
int iterativeFactorial(int n) {
    int result = 1;
    for (int i = 2; i <= n; i++) {
        result *= i;
    }
    return result;
}

// 演示栈大小限制的函数
void demonstrateStackLimits() {
    // 大型局部数组可能导致栈溢出
    // int largeArray[1000000];  // 危险！
    
    // 相反，使用动态分配
    int* largeArray = malloc(1000000 * sizeof(int));
    if (largeArray != NULL) {
        printf("大型数组分配成功\n");
        free(largeArray);  // 重要：释放内存
    }
}

int main() {
    printf("尾递归阶乘 5: %d\n", 
           tailRecursiveFactorial(5, 1));
    
    printf("迭代阶乘 5: %d\n", 
           iterativeFactorial(5));
    
    // 小心深度递归
    printf("深度递归（小）: %d\n", deepRecursion(100));
    
    demonstrateStackLimits();
    
    return 0;
}
```
</UniversalEditor>

## 4. 函数指针

### 4.1 函数指针基础

<UniversalEditor title="函数指针" compare={true}>
```javascript !! js
// JavaScript - 函数是一等对象
function add(a, b) {
    return a + b;
}

function multiply(a, b) {
    return a * b;
}

function subtract(a, b) {
    return a - b;
}

// 函数可以赋值给变量
let operation = add;
console.log("使用函数指针:", operation(5, 3));

// 函数可以作为参数传递
function calculate(a, b, func) {
    return func(a, b);
}

console.log("加法:", calculate(10, 5, add));
console.log("乘法:", calculate(10, 5, multiply));
console.log("减法:", calculate(10, 5, subtract));

// 函数可以存储在数组中
let operations = [add, multiply, subtract];
for (let i = 0; i < operations.length; i++) {
    console.log(`操作 ${i}:`, operations[i](10, 2));
}

// 函数可以从函数返回
function getOperation(type) {
    switch (type) {
        case 'add': return add;
        case 'multiply': return multiply;
        case 'subtract': return subtract;
        default: return add;
    }
}

let selectedOp = getOperation('multiply');
console.log("选择的操作:", selectedOp(6, 7));
```

```c !! c
#include <stdio.h>

// 函数声明
int add(int a, int b);
int multiply(int a, int b);
int subtract(int a, int b);

// 函数定义
int add(int a, int b) {
    return a + b;
}

int multiply(int a, int b) {
    return a * b;
}

int subtract(int a, int b) {
    return a - b;
}

// 接受函数指针作为参数的函数
int calculate(int a, int b, int (*operation)(int, int)) {
    return operation(a, b);
}

// 返回函数指针的函数
int (*getOperation(char type))(int, int) {
    switch (type) {
        case 'a': return add;
        case 'm': return multiply;
        case 's': return subtract;
        default: return add;
    }
}

int main() {
    // 函数指针声明
    int (*operation)(int, int);
    
    // 将函数赋值给指针
    operation = add;
    printf("使用函数指针: %d\n", operation(5, 3));
    
    // 将函数指针传递给另一个函数
    printf("加法: %d\n", calculate(10, 5, add));
    printf("乘法: %d\n", calculate(10, 5, multiply));
    printf("减法: %d\n", calculate(10, 5, subtract));
    
    // 函数指针数组
    int (*operations[3])(int, int) = {add, multiply, subtract};
    char* names[] = {"add", "multiply", "subtract"};
    
    for (int i = 0; i < 3; i++) {
        printf("%s: %d\n", names[i], operations[i](10, 2));
    }
    
    // 从函数获取函数指针
    int (*selectedOp)(int, int) = getOperation('m');
    printf("选择的操作: %d\n", selectedOp(6, 7));
    
    return 0;
}
```
</UniversalEditor>

### 4.2 函数指针作为回调

<UniversalEditor title="函数指针作为回调" compare={true}>
```javascript !! js
// JavaScript - 回调函数
function processArray(arr, callback) {
    let result = [];
    for (let i = 0; i < arr.length; i++) {
        result.push(callback(arr[i]));
    }
    return result;
}

// 回调函数
function double(x) {
    return x * 2;
}

function square(x) {
    return x * x;
}

function isEven(x) {
    return x % 2 === 0;
}

// 使用回调
let numbers = [1, 2, 3, 4, 5];
console.log("原始:", numbers);
console.log("翻倍:", processArray(numbers, double));
console.log("平方:", processArray(numbers, square));

// 带回调的过滤
function filterArray(arr, predicate) {
    let result = [];
    for (let i = 0; i < arr.length; i++) {
        if (predicate(arr[i])) {
            result.push(arr[i]);
        }
    }
    return result;
}

console.log("偶数:", filterArray(numbers, isEven));

// 带回调的排序
function compareNumbers(a, b) {
    return a - b;
}

let unsorted = [3, 1, 4, 1, 5, 9, 2, 6];
unsorted.sort(compareNumbers);
console.log("排序后:", unsorted);
```

```c !! c
#include <stdio.h>
#include <stdlib.h>

// 函数指针类型定义，提高可读性
typedef int (*OperationFunc)(int);
typedef int (*ComparisonFunc)(int, int);

// 使用回调处理数组的函数
void processArray(int arr[], int size, OperationFunc operation) {
    for (int i = 0; i < size; i++) {
        arr[i] = operation(arr[i]);
    }
}

// 使用回调过滤数组的函数
int* filterArray(int arr[], int size, int (*predicate)(int), int* resultSize) {
    int* result = malloc(size * sizeof(int));
    *resultSize = 0;
    
    for (int i = 0; i < size; i++) {
        if (predicate(arr[i])) {
            result[*resultSize] = arr[i];
            (*resultSize)++;
        }
    }
    
    return result;
}

// 回调函数
int doubleValue(int x) {
    return x * 2;
}

int squareValue(int x) {
    return x * x;
}

int isEven(int x) {
    return x % 2 == 0;
}

int isPositive(int x) {
    return x > 0;
}

// 排序的比较函数
int compareAscending(int a, int b) {
    return a - b;
}

int compareDescending(int a, int b) {
    return b - a;
}

// 带比较函数的简单冒泡排序
void bubbleSort(int arr[], int size, ComparisonFunc compare) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            if (compare(arr[j], arr[j + 1]) > 0) {
                // 交换
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

void printArray(int arr[], int size) {
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
}

int main() {
    int numbers[] = {1, 2, 3, 4, 5};
    int size = 5;
    
    printf("原始数组: ");
    printArray(numbers, size);
    
    // 使用不同回调处理
    int doubled[5];
    for (int i = 0; i < size; i++) {
        doubled[i] = numbers[i];
    }
    processArray(doubled, size, doubleValue);
    printf("翻倍: ");
    printArray(doubled, size);
    
    // 过滤数组
    int resultSize;
    int* evenNumbers = filterArray(numbers, size, isEven, &resultSize);
    printf("偶数: ");
    printArray(evenNumbers, resultSize);
    free(evenNumbers);
    
    // 排序数组
    int unsorted[] = {3, 1, 4, 1, 5, 9, 2, 6};
    int unsortedSize = 8;
    
    printf("未排序: ");
    printArray(unsorted, unsortedSize);
    
    bubbleSort(unsorted, unsortedSize, compareAscending);
    printf("升序排序: ");
    printArray(unsorted, unsortedSize);
    
    bubbleSort(unsorted, unsortedSize, compareDescending);
    printf("降序排序: ");
    printArray(unsorted, unsortedSize);
    
    return 0;
}
```
</UniversalEditor>

## 5. 可变参数和高级特性

### 5.1 可变参数函数

<UniversalEditor title="可变参数" compare={true}>
```javascript !! js
// JavaScript - 剩余参数和 arguments 对象
function sum(...numbers) {
    return numbers.reduce((a, b) => a + b, 0);
}

function average(...numbers) {
    if (numbers.length === 0) return 0;
    return numbers.reduce((a, b) => a + b, 0) / numbers.length;
}

function formatString(template, ...values) {
    return template.replace(/\{(\d+)\}/g, (match, index) => {
        return values[index] || match;
    });
}

// 使用可变参数
console.log("和:", sum(1, 2, 3, 4, 5));
console.log("平均值:", average(10, 20, 30, 40));
console.log("格式化:", formatString("Hello {0}, you are {1} years old", "Alice", 25));

// arguments 对象（遗留）
function legacySum() {
    let total = 0;
    for (let i = 0; i < arguments.length; i++) {
        total += arguments[i];
    }
    return total;
}

console.log("遗留求和:", legacySum(1, 2, 3, 4, 5));
```

```c !! c
#include <stdio.h>
#include <stdarg.h>

// 可变参数函数
int sum(int count, ...) {
    va_list args;
    va_start(args, count);
    
    int total = 0;
    for (int i = 0; i < count; i++) {
        total += va_arg(args, int);
    }
    
    va_end(args);
    return total;
}

// 可变参数求平均值
double average(int count, ...) {
    va_list args;
    va_start(args, count);
    
    double total = 0.0;
    for (int i = 0; i < count; i++) {
        total += va_arg(args, double);
    }
    
    va_end(args);
    return count > 0 ? total / count : 0.0;
}

// 可变参数字符串格式化
void printFormatted(const char* format, ...) {
    va_list args;
    va_start(args, format);
    
    vprintf(format, args);
    
    va_end(args);
}

// 不同类型的可变参数
void printMixed(const char* prefix, int count, ...) {
    va_list args;
    va_start(args, count);
    
    printf("%s: ", prefix);
    for (int i = 0; i < count; i++) {
        // 假设交替的 int 和 double
        if (i % 2 == 0) {
            int val = va_arg(args, int);
            printf("%d ", val);
        } else {
            double val = va_arg(args, double);
            printf("%.2f ", val);
        }
    }
    printf("\n");
    
    va_end(args);
}

int main() {
    // 使用可变参数
    printf("5 个数的和: %d\n", sum(5, 1, 2, 3, 4, 5));
    printf("3 个数的和: %d\n", sum(3, 10, 20, 30));
    
    printf("4 个数的平均值: %.2f\n", average(4, 10.0, 20.0, 30.0, 40.0));
    
    printFormatted("Hello %s, you are %d years old\n", "Alice", 25);
    printFormatted("Temperature: %.1f°C, Humidity: %d%%\n", 23.5, 65);
    
    printMixed("混合值", 6, 10, 3.14, 20, 2.718, 30, 1.414);
    
    return 0;
}
```
</UniversalEditor>

### 5.2 内联函数和优化

<UniversalEditor title="内联函数" compare={true}>
```javascript !! js
// JavaScript - 函数优化
function simpleAdd(a, b) {
    return a + b;
}

// 现代 JavaScript 引擎优化小函数
const optimizedAdd = (a, b) => a + b;

// 函数内联（引擎优化）
function processData(data) {
    let result = 0;
    for (let i = 0; i < data.length; i++) {
        result += optimizedAdd(data[i], 1);  // 可能被内联
    }
    return result;
}

// 性能测量
function measurePerformance(func, iterations) {
    const start = performance.now();
    for (let i = 0; i < iterations; i++) {
        func(i, i + 1);
    }
    const end = performance.now();
    return end - start;
}

console.log("简单函数时间:", measurePerformance(simpleAdd, 1000000));
console.log("优化函数时间:", measurePerformance(optimizedAdd, 1000000));
```

```c !! c
#include <stdio.h>
#include <time.h>

// 普通函数
int regularAdd(int a, int b) {
    return a + b;
}

// 内联函数（编译器建议）
inline int inlineAdd(int a, int b) {
    return a + b;
}

// 静态内联（更明确）
static inline int staticInlineAdd(int a, int b) {
    return a + b;
}

// 宏（预处理器替换）
#define MACRO_ADD(a, b) ((a) + (b))

// 使用内联函数的函数
int processData(int data[], int size) {
    int result = 0;
    for (int i = 0; i < size; i++) {
        // 这些调用可能被编译器内联
        result += inlineAdd(data[i], 1);
        result += staticInlineAdd(data[i], 2);
        result += MACRO_ADD(data[i], 3);
    }
    return result;
}

// 性能测量函数
double measurePerformance(int (*func)(int, int), int iterations) {
    clock_t start = clock();
    
    for (int i = 0; i < iterations; i++) {
        func(i, i + 1);
    }
    
    clock_t end = clock();
    return ((double)(end - start)) / CLOCKS_PER_SEC;
}

int main() {
    int data[] = {1, 2, 3, 4, 5};
    int size = 5;
    
    printf("处理的数据: %d\n", processData(data, size));
    
    // 性能比较
    int iterations = 1000000;
    
    printf("普通函数时间: %.6f 秒\n", 
           measurePerformance(regularAdd, iterations));
    
    printf("内联函数时间: %.6f 秒\n", 
           measurePerformance(inlineAdd, iterations));
    
    printf("静态内联时间: %.6f 秒\n", 
           measurePerformance(staticInlineAdd, iterations));
    
    // 注意：实际性能取决于编译器优化
    // 在不同编译器和优化级别下可能有所不同
    
    return 0;
}
```
</UniversalEditor>

## 6. 练习

### 练习 1: 递归数组处理
编写一个 C 函数，递归查找数组中的最大值。

<UniversalEditor title="练习 1: 递归最大值" compare={true}>
```javascript !! js
// JavaScript 解决方案
function findMaxRecursive(arr, index = 0) {
    if (index >= arr.length) {
        return -Infinity;
    }
    
    let current = arr[index];
    let rest = findMaxRecursive(arr, index + 1);
    
    return current > rest ? current : rest;
}

// 测试
let numbers = [3, 7, 2, 9, 1, 8, 5];
console.log("最大值:", findMaxRecursive(numbers));
```

```c !! c
#include <stdio.h>
#include <limits.h>

// C 解决方案
int findMaxRecursive(int arr[], int size, int index) {
    // 基本情况：如果到达末尾
    if (index >= size) {
        return INT_MIN;
    }
    
    // 获取当前元素
    int current = arr[index];
    
    // 递归查找剩余数组的最大值
    int restMax = findMaxRecursive(arr, size, index + 1);
    
    // 返回当前值和剩余值中的较大者
    return (current > restMax) ? current : restMax;
}

int main() {
    int numbers[] = {3, 7, 2, 9, 1, 8, 5};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    
    int max = findMaxRecursive(numbers, size, 0);
    printf("最大值: %d\n", max);
    
    return 0;
}
```
</UniversalEditor>

### 练习 2: 函数指针计算器
使用函数指针创建计算器。

<UniversalEditor title="练习 2: 函数指针计算器" compare={true}>
```javascript !! js
// JavaScript 解决方案
const calculator = {
    add: (a, b) => a + b,
    subtract: (a, b) => a - b,
    multiply: (a, b) => a * b,
    divide: (a, b) => b !== 0 ? a / b : NaN
};

function calculate(operation, a, b) {
    if (calculator[operation]) {
        return calculator[operation](a, b);
    }
    return NaN;
}

// 测试
console.log("10 + 5 =", calculate('add', 10, 5));
console.log("10 - 5 =", calculate('subtract', 10, 5));
console.log("10 * 5 =", calculate('multiply', 10, 5));
console.log("10 / 5 =", calculate('divide', 10, 5));
```

```c !! c
#include <stdio.h>

// 计算器操作的函数指针类型
typedef double (*Operation)(double, double);

// 计算器函数
double add(double a, double b) {
    return a + b;
}

double subtract(double a, double b) {
    return a - b;
}

double multiply(double a, double b) {
    return a * b;
}

double divide(double a, double b) {
    return b != 0 ? a / b : 0;
}

// 使用函数指针的计算器函数
double calculate(Operation operation, double a, double b) {
    return operation(a, b);
}

int main() {
    double a = 10.0, b = 5.0;
    
    printf("%.1f + %.1f = %.1f\n", a, b, calculate(add, a, b));
    printf("%.1f - %.1f = %.1f\n", a, b, calculate(subtract, a, b));
    printf("%.1f * %.1f = %.1f\n", a, b, calculate(multiply, a, b));
    printf("%.1f / %.1f = %.1f\n", a, b, calculate(divide, a, b));
    
    return 0;
}
```
</UniversalEditor>

## 7. 总结

### 涵盖的核心概念

1. **函数声明和定义**: C 函数需要显式声明，具有严格的参数类型
2. **栈帧**: 每次函数调用都创建一个栈帧，包含局部变量、参数和返回地址
3. **参数传递**: C 默认使用按值传递，但指针可以实现按引用传递行为
4. **递归**: C 支持递归，但需要小心栈管理以避免溢出
5. **函数指针**: 实现动态函数选择和回调机制
6. **可变参数**: 使用 `stdarg.h` 允许函数接受可变数量的参数
7. **内联函数**: 向编译器提供性能优化提示

### 内存管理考虑

- **栈变量**: 随函数调用自动分配和释放
- **栈溢出**: 深度递归可能导致栈溢出；对大型问题使用迭代
- **函数指针**: 与动态分配一起使用时需要小心内存管理
- **可变参数**: 需要正确使用 `va_start` 和 `va_end` 进行初始化和清理

### 最佳实践

1. **始终声明函数原型**在使用前
2. **在函数声明中使用有意义的参数名**
3. **在递归函数中检查栈溢出**
4. **使用函数指针**实现灵活、可重用的代码
5. **对性能关键代码优先使用迭代而非递归**
6. **对小而频繁调用的函数使用内联函数**
7. **小心处理可变参数**并进行适当的类型检查

### 性能提示

- **内联函数**: 对小而频繁调用的函数使用 `inline` 关键字
- **函数指针**: 可能增加轻微开销但提供灵活性
- **递归 vs 迭代**: 根据问题复杂性和栈使用情况选择
- **栈管理**: 了解环境中的栈大小限制

理解 C 函数和栈管理对于编写高效、安全、可维护的代码至关重要。这些概念为系统编程和性能优化等更高级主题奠定了基础。 